#include "Tkgles.h"
#ifndef __Context_h_
#include "Context.h"
#endif
#include <stdio.h>


EXPORT void RecordError(GLenum error){


}

EXPORT void ToggleState(GLenum name, GLboolean state){

	Context * context = getContext();

	switch (name){
		case GL_POINT_SMOOTH:
			context->State.PointSmooth = state;
			break;
		case GL_LINE_SMOOTH:
			context->State.LineSmooth = state;
			break;
		case GL_SCISSOR_TEST:
			context->State.ScissorTest = state;
			break;
		case GL_COLOR_MATERIAL:
			context->State.ColorMaterial = state;
			break;
		case GL_NORMALIZE:
			context->State.Normalize = state;
			break;
		case GL_RESCALE_NORMAL:
			context->State.RescaleNormal = state;
			break;
		case GL_POLYGON_OFFSET_FILL:
			context->State.PolygonOffsetFill = state;
			break;
		case GL_VERTEX_ARRAY:
			context->State.VertexArray = state;
			break;
		case GL_NORMAL_ARRAY:
			context->State.NormalArray = state;
			break;
		case GL_COLOR_ARRAY:
			context->State.ColorArray = state;
			break;
		case GL_TEXTURE_COORD_ARRAY:
			context->State.TextureCoordArray = state;
			break;
		case GL_MULTISAMPLE:
			context->State.MultiSample = state;
			break;
		case GL_SAMPLE_ALPHA_TO_COVERAGE:
			context->State.SampleAlphaToCoverage = state;
			break;
		case GL_SAMPLE_ALPHA_TO_ONE:
			context->State.SampleAlphaToOne = state;
			break;
		case GL_SAMPLE_COVERAGE:
			context->State.SampleCoverage = state;
			break;
		case GL_CLIP_PLANE0:
		case GL_CLIP_PLANE1:
		case GL_CLIP_PLANE2:
		case GL_CLIP_PLANE3:
		case GL_CLIP_PLANE4:
		case GL_CLIP_PLANE5:
			context->State.ClipPlane[name - GL_CLIP_PLANE0] = state;
			break;
		case GL_LIGHTING:
			context->State.Lighting = state;
			break;
		case GL_LIGHT0:
		case GL_LIGHT1:
		case GL_LIGHT2:
		case GL_LIGHT3:
		case GL_LIGHT4:
		case GL_LIGHT5:
		case GL_LIGHT6:
		case GL_LIGHT7:
			context->State.Light[name - GL_LIGHT0] = state;
			break;
	} 

}


EXPORT void Transform ( GLint index ){
	//printf("Render point %d\n",index);

	GLvoid * pt = NULL;
	Vect4D ObjectCoord;

	Context * context = getContext();

	if ( context->VertexArray.type == GL_BYTE || context->VertexArray.type == GL_UNSIGNED_BYTE){
		if (context->VertexArray.stride == 0){
			pt = context->VertexArray.pointer + index *(sizeof(GLbyte)*context->VertexArray.size);
		} else if (context->VertexArray.stride > 0){
			pt = context->VertexArray.pointer + context->VertexArray.stride*sizeof(GLbyte);
		}
		ObjectCoord.x = (GLfloat)(*(GLbyte *)pt);
		ObjectCoord.y = (GLfloat)*(GLbyte*)(pt + sizeof(GLbyte));
		ObjectCoord.z = (GLfloat)*(GLbyte*)(pt + 2*sizeof(GLbyte));
		ObjectCoord.t = (GLfloat)*(GLbyte*)(pt + 3*sizeof(GLbyte));
	} else if ( context->VertexArray.type == GL_SHORT){
		if (context->VertexArray.stride == 0){
			pt = context->VertexArray.pointer + index *(sizeof(GLshort)*context->VertexArray.size);
		} else if (context->VertexArray.stride > 0){
			pt = context->VertexArray.pointer + context->VertexArray.stride*sizeof(GLbyte);
		}
		ObjectCoord.x = (GLfloat)(*(GLshort *)pt);
		ObjectCoord.y = (GLfloat)*(GLshort*)(pt + sizeof(GLshort));
		ObjectCoord.z = (GLfloat)*(GLshort*)(pt + 2*sizeof(GLshort));
		ObjectCoord.t = (GLfloat)*(GLshort*)(pt + 3*sizeof(GLshort));
	} else if ( context->VertexArray.type == GL_FIXED){
		if (context->VertexArray.stride == 0){
			pt = context->VertexArray.pointer + index *(sizeof(GLfixed)*context->VertexArray.size);
		} else if (context->VertexArray.stride > 0){
			pt = context->VertexArray.pointer + context->VertexArray.stride*sizeof(GLbyte);
		}
		ObjectCoord.x = (GLfloat)(*(GLfixed *)pt);
		ObjectCoord.y = (GLfloat)*(GLfixed*)(pt + sizeof(GLfixed));
		ObjectCoord.z = (GLfloat)*(GLfixed*)(pt + 2*sizeof(GLfixed));
		ObjectCoord.t = (GLfloat)*(GLfixed*)(pt + 3*sizeof(GLfixed));
	} else if ( context->VertexArray.type == GL_FLOAT){
		if (context->VertexArray.stride == 0){
			pt = context->VertexArray.pointer + index *(sizeof(GLfloat)*context->VertexArray.size);
		} else if (context->VertexArray.stride > 0){
			pt = context->VertexArray.pointer + context->VertexArray.stride*sizeof(GLbyte);
		}
		ObjectCoord.x = (*(GLfloat *)pt);
		ObjectCoord.y = *(GLfloat*)(pt + sizeof(GLfloat));
		if (context->VertexArray.size == 3)
			ObjectCoord.z = *(GLfloat*)(pt + 2*sizeof(GLfloat));
		if (context->VertexArray.size == 4)
			ObjectCoord.t = *(GLfloat*)(pt + 3*sizeof(GLfloat));
		else 
			ObjectCoord.t = 1;
	} 
	//printf("ObjectCoord : %f, %f, %f, %f\n", ObjectCoord.x, ObjectCoord.y, ObjectCoord.z, ObjectCoord.t);

	MatrixMultiply(&(context->Matrix.ModelViewStack[context->Matrix.ModelViewStackPointer]),
					&ObjectCoord,
					&(context->VertexArray.EyeCoord[index]));
	//printf("Eye Coord: %f, %f, %f, %f\n",context->VertexArray.EyeCoord[index].x, context->VertexArray.EyeCoord[index].y,
//															context->VertexArray.EyeCoord[index].z,context->VertexArray.EyeCoord[index].t);
												
	MatrixMultiply(&(context->Matrix.ProjectionStack[context->Matrix.ProjectionStackPointer]),
					&(context->VertexArray.EyeCoord[index]),
					&(context->VertexArray.ClipCoord[index]));
	//printf("Clip Coord: %f, %f, %f, %f\n",context->VertexArray.ClipCoord[index].x, context->VertexArray.ClipCoord[index].y,
	//													context->VertexArray.ClipCoord[index].z,context->VertexArray.ClipCoord[index].t);
				
	PerspectiveDevise(&(context->VertexArray.ClipCoord[index]),
					  &(context->VertexArray.NDCoord[index]));
	//printf("ND Coord: %f, %f, %f\n",context->VertexArray.NDCoord[index].x, context->VertexArray.NDCoord[index].y,
	//											context->VertexArray.NDCoord[index].z);
	ViewportTransform( &(context->VertexArray.NDCoord[index]),
					   &(context->VertexArray.WindowCoord[index]));
	//printf("Window Coord: x : %f, y : %f, z: %f\n",context->VertexArray.WindowCoord[index].x, context->VertexArray.WindowCoord[index].y, context->VertexArray.WindowCoord[index].z);
			   
	
}
